'''
作者：刘宇轩
文件名称：计算器GUI
时间：2021.5.7
'''

import tkinter as tk
from tkinter import ttk
import math


def get(entry, argu):
    indata = entry.get()
    if (indata[-1:] == '+') and (argu in ['+', '*', '/', '%', '**']):
        return
    if (indata[-1:] == '-') and (argu in ['+', '*', '/', '%', '**']):
        return
    if (indata[-1:] == '*') and (argu in ['+', '/', '%', '**']):
        return
    if (indata[-1:] == '/') and (argu in ['+', '*', '%', '**']):
        return
    if (indata[-1:] == '&') and (argu in ['+', '*', '/', '%', '**']):
        return
    if (indata[-2:] == '+-') and (argu in ['+', '-', '*', '/', '%', '**']):
        return
    if (indata[-2:] == '--') and (argu in ['+', '-', '*', '/', '%', '**']):
        return
    if (indata[-2:] == '**') and (argu in ['+', '*', '/', '%', '**']):
        return
    entry.insert("end", argu)


def back(entry):
    l = len(entry.get())
    entry.delete(l - 1)


def clear(entry):
    entry.delete(0, "end")


def calculate(entry):
    date = entry.get()
    if not date:
        return
    else:
        for i in date:
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '+', '=', '*', '/', '%', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(2)
        else:
            clear(entry)
            result = str(eval(date))
            if len(result) > 20:
                entry.insert("end", "Value overflow")
            else:
                entry.insert("end", result)


def error(t):
    win0 = tk.Tk()
    win0.title("")
    if t == 1:
        l1 = ttk.Label(win0, text="无法运算")
        l1.grid(column=0, row=0, columnspan=2)
    elif t == 2:
        l1 = ttk.Label(win0, text="Illegal character")
        l1.grid(column=0, row=0, columnspan=2)
    b1 = ttk.Button(win0, text='关闭', command=lambda: win0.destroy())
    b1.grid(column=0, row=1)
    win0.mainloop()


def f1_get(entry):
    date = entry.get()
    if not date:
        return
    else:
        for i in date:
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
        else:
            entry.delete(0, "end")
            date = float(date)
            result = math.sqrt(date)
            entry.insert("end", result)


def f2down_get(entry):
    date = entry.get()
    if not date:
        return
    else:
        for i in date:
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
            return
        else:
            entry.delete(0, "end")
            date = float(date)
            result = math.trunc(date)
            entry.insert("end", result)


def f2up_get(entry):
    date = entry.get()
    if not date:
        return
    else:
        for i in date:
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
            return
        else:
            entry.delete(0, "end")
            date = float(date)
            result = math.ceil(date)
            entry.insert("end", result)


def f3_get(entry2, entry3, entry4):
    date1 = entry2.get()
    date2 = entry3.get()
    if (not date1) or (not date2):
        return
    else:
        for i in (date1 or date2):
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
        else:
            entry4.delete(0, "end")
            date1 = float(date1)
            date2 = float(date2)
            result = math.log(date1, date2)
            entry4.insert("end", result)


def f3_clear(entry2, entry3, entry4):
    entry2.delete(0, "end")
    entry3.delete(0, "end")
    entry4.delete(0, "end")


def f3():
    win2 = tk.Tk()
    win2.title("对数运算")
    l1 = ttk.Label(win2, text="对数运算")
    l1.grid(column=0, row=0, columnspan=3)
    l1 = ttk.Label(win2, text="请输入真数")
    l1.grid(column=0, row=1)
    l1 = ttk.Label(win2, text="请输入底数")
    l1.grid(column=0, row=2)
    l1 = ttk.Label(win2, text="结果为")
    l1.grid(column=0, row=3)
    entry2 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry2.grid(row=1, column=1, columnspan=2, padx=20, pady=5)
    entry3 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry3.grid(row=2, column=1, columnspan=2, padx=20, pady=5)
    entry4 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry4.grid(row=3, column=1, columnspan=2, padx=20, pady=5)
    b1 = ttk.Button(win2, text='log运算', command=lambda: f3_get(entry2, entry3, entry4))
    b1.grid(column=2, row=4)
    b2 = ttk.Button(win2, text='clear', command=lambda: f3_clear(entry2, entry3, entry4))
    b2.grid(column=1, row=4)
    win2.mainloop()


def f4_get(entry5, entry6, entry7):
    date1 = entry5.get()
    date2 = entry6.get()
    if (not date1) or (not date2):
        return
    else:
        for i in (date1 or date2):
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
        else:
            entry7.delete(0, "end")
            date1 = int(date1)
            date2 = int(date2)
            result = math.gcd(date1, date2)
            entry7.insert("end", result)


def f4_clear(entry5, entry6, entry7):
    entry5.delete(0, "end")
    entry6.delete(0, "end")
    entry7.delete(0, "end")


def f4():
    win2 = tk.Tk()
    win2.title("最大公约数运算")
    l1 = ttk.Label(win2, text="最大公约数运算")
    l1.grid(column=0, row=0, columnspan=3)
    l1 = ttk.Label(win2, text="请输入第一个数")
    l1.grid(column=0, row=1)
    l1 = ttk.Label(win2, text="请输入第二个数")
    l1.grid(column=0, row=2)
    l1 = ttk.Label(win2, text="结果为")
    l1.grid(column=0, row=3)
    entry5 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry5.grid(row=1, column=1, columnspan=2, padx=20, pady=5)
    entry6 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry6.grid(row=2, column=1, columnspan=2, padx=20, pady=5)
    entry7 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry7.grid(row=3, column=1, columnspan=2, padx=20, pady=5)
    b1 = ttk.Button(win2, text='运算', command=lambda: f4_get(entry5, entry6, entry7))
    b1.grid(column=2, row=4)
    b2 = ttk.Button(win2, text='clear', command=lambda: f4_clear(entry5, entry6, entry7))
    b2.grid(column=1, row=4)
    win2.mainloop()


def f5_get(entry8, s):
    date = entry8.get()
    if not date:
        return
    else:
        for i in date:
            if i not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.']:
                t = 0
            else:
                t = 1
        if t == 0:
            error(1)
        else:
            entry8.delete(0, "end")
            date = float(date)
            if s == 2:
                result = math.degrees(date)
            if s == 3:
                result = math.radians(date)
            if s == 4:
                result = math.sin(math.pi * date)
            if s == 5:
                result = math.cos(math.pi * date)
            if s == 6:
                result = math.tan(math.pi * date)
            entry8.insert("end", result)


def f5():
    win2 = tk.Tk()
    win2.title("三角函数运算")
    l1 = ttk.Label(win2, text="三角函数运算")
    l1.grid(column=0, row=0, columnspan=3)
    entry8 = ttk.Entry(win2, width=20, justify="right", font=1)
    entry8.grid(row=1, column=0, columnspan=3, padx=20, pady=5)
    b1 = ttk.Button(win2, text='弧度转换角度', command=lambda: f5_get(entry8, 2))
    b1.grid(column=1, row=2)
    b2 = ttk.Button(win2, text='角度转换弧度', command=lambda: f5_get(entry8, 3))
    b2.grid(column=2, row=2)
    b3 = ttk.Button(win2, text='sin(π*n)', command=lambda: f5_get(entry8, 4))
    b3.grid(column=0, row=3)
    b4 = ttk.Button(win2, text='cos(π*n)', command=lambda: f5_get(entry8, 3))
    b4.grid(column=1, row=3)
    b5 = ttk.Button(win2, text='tan(π*n)', command=lambda: f5_get(entry8, 3))
    b5.grid(column=2, row=3)
    b6 = ttk.Button(win2, text='clear', command=lambda: entry8.delete(0, "end"))
    b6.grid(column=0, row=2)
    win2.mainloop()


win = tk.Tk()
win.title("计算器")
menubar = tk.Menu(win)
menubar.add_command(label='向下取整',command=lambda:f2down_get(entry))
menubar.add_command(label='开方',command=lambda: f1_get(entry))
menubar.add_command(label='对数函数',command=lambda: f3())
menubar.add_command(label='最大公约数',command=lambda: f4())
menubar.add_command(label='三角函数',command=lambda: f5())


win.config(menu=menubar)

entry = ttk.Entry(win, justify="right", font=1)
entry.grid(row=0, column=0, columnspan=6, padx=20, pady=5)
b0 = ttk.Button(win, text='0', command=lambda: get(entry, '0'))
b0.grid(column=1, row=4)
b1 = ttk.Button(win, text='1', command=lambda: get(entry, '1'))
b1.grid(column=0, row=3)
b2 = ttk.Button(win, text='2', command=lambda: get(entry, '2'))
b2.grid(column=1, row=3)
b3 = ttk.Button(win, text='3', command=lambda: get(entry, '3'))
b3.grid(column=2, row=3)
b4 = ttk.Button(win, text='4', command=lambda: get(entry, '4'))
b4.grid(column=0, row=2)
b5 = ttk.Button(win, text='5', command=lambda: get(entry, '5'))
b5.grid(column=1, row=2)
b6 = ttk.Button(win, text='6', command=lambda: get(entry, '6'))
b6.grid(column=2, row=2)
b7 = ttk.Button(win, text='7', command=lambda: get(entry, '7'))
b7.grid(column=0, row=1)
b8 = ttk.Button(win, text='8', command=lambda: get(entry, '8'))
b8.grid(column=1, row=1)
b9 = ttk.Button(win, text='9', command=lambda: get(entry, '9'))
b9.grid(column=2, row=1)
bb0 = ttk.Button(win, text='.', command=lambda: get(entry, '.'))
bb0.grid(column=2, row=4)
bb1 = ttk.Button(win, text='+', command=lambda: get(entry, '+'))
bb1.grid(column=3, row=1)
bb2 = ttk.Button(win, text='-', command=lambda: get(entry, '-'))
bb2.grid(column=3, row=2)
bb3 = ttk.Button(win, text='*', command=lambda: get(entry, '*'))
bb3.grid(column=3, row=3)
bb4 = ttk.Button(win, text='/', command=lambda: get(entry, '/'))
bb4.grid(column=3, row=4)
bb5 = ttk.Button(win, text='回退', command=lambda: back(entry))
bb5.grid(column=0, row=4)
bb6 = ttk.Button(win, text='x^n', command=lambda: get(entry, '**'))
bb6.grid(column=5, row=1)
bb7 = ttk.Button(win, text='mod', command=lambda: get(entry, '%'))
bb7.grid(column=5, row=2)
bb8 = ttk.Button(win, text='clear', command=lambda: clear(entry))
bb8.grid(column=5, row=3)
bb9 = ttk.Button(win, text='=', command=lambda: calculate(entry))
bb9.grid(column=5, row=4, )

win.mainloop()